package com.manager.common.utils;

import com.jcraft.jsch.Channel;
import com.manager.model.DockerContainerStats;
import com.manager.model.DockerLogs;
import com.manager.model.LinuxBaseMonitor;
import org.apache.commons.lang.StringUtils;

import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class DataTools {

    private static List<DockerContainerStats> dockerContainerStatsList = new ArrayList<DockerContainerStats>();

    private static Map<String,DockerLogs> dockerLogsMap = new HashMap<>();

    private static List<LinuxBaseMonitor> linuxBaseMonitorList = new ArrayList<>();

    private static Map<String,Object> cacheLinuxMonitor = new HashMap<>();

    public static String containerPrefix = "mimic-container";

    private static boolean tcpConnected = false;

    private static Object tcpConnectedLock = new Object();

    private static int lineCount = 60;

    private static long logTimeOut = 60 * 1000;

    public static ExecutorService executorService = Executors.newFixedThreadPool(10);

    public static void  addAll(List<DockerContainerStats> dockerContainerStats){
        synchronized (dockerContainerStatsList){
            dockerContainerStatsList.clear();
            dockerContainerStatsList.addAll(dockerContainerStats);
        }
    }

    public static List<DockerContainerStats> getContainerStats(){
        synchronized (dockerContainerStatsList){
            return dockerContainerStatsList;
        }
    }

    public static DockerContainerStats getContainerStatsById(String containerId){
        synchronized (dockerContainerStatsList){
            for(DockerContainerStats dockerContainerStats: dockerContainerStatsList){
                if(dockerContainerStats.getContainerId().equals(containerId)){
                    return dockerContainerStats;
                }
            }
            return new DockerContainerStats();
        }
    }

    public static String getDockerContainerLog(String containerId){
        synchronized (dockerLogsMap){
            if(!dockerLogsMap.containsKey(containerId)){
                DockerLogs dockerLogs = new DockerLogs();
                dockerLogs.setContainerId(containerId);
                dockerLogsMap.put(containerId,dockerLogs);
                return "";
            }
            DockerLogs dockerLogs = dockerLogsMap.get(containerId);
            dockerLogs.setLastGetTime(System.currentTimeMillis());
            List<String> temp = dockerLogs.getLogs();
            String str = StringUtils.join(temp,"<br />");
            dockerLogs.getLogs().clear();
            return str == null ? "" : str ;
        }
    }

    public static boolean putDockerContainerLog(String containerId, String log, Channel channel){
        synchronized (dockerLogsMap){
            if(!dockerLogsMap.containsKey(containerId)){
                return false;
            }
            DockerLogs logs = dockerLogsMap.get(containerId);
            logs.setChannel(channel);
            if(System.currentTimeMillis() - logs.getLastGetTime() >= logTimeOut){
                dockerLogsMap.remove(containerId);
                return false;
            }
            logs.getLogs().add(log);
            dockerLogsMap.put(containerId,logs);
            return true;
        }
    }

    public static boolean existDockerLogs(String containerId){
        synchronized (dockerLogsMap){
            return dockerLogsMap.containsKey(containerId);
        }
    }

    public static void checkLogsTimeOut(){
        synchronized (dockerLogsMap){
            for(String key: dockerLogsMap.keySet()){
                DockerLogs  dockerLogs = dockerLogsMap.get(key);
                if(System.currentTimeMillis() - dockerLogs.getLastGetTime() >= logTimeOut){
                    dockerLogs.getChannel().disconnect();
                    dockerLogsMap.remove(key);
                }
            }
        }
    }

    public static void addLinuxBaseMonitor(LinuxBaseMonitor linuxBaseMonitor){
        synchronized (linuxBaseMonitorList){
            if(linuxBaseMonitorList.size() >= lineCount){
                linuxBaseMonitorList.remove(0);
            }
            linuxBaseMonitorList.add(linuxBaseMonitor);
        }
    }

    public static List<LinuxBaseMonitor> getLinuxBaseMonitorList(){
        synchronized (linuxBaseMonitorList){
            return linuxBaseMonitorList;
        }
    }

    public static void addCacheLinuxMonitor(String key,Object object){
        synchronized (cacheLinuxMonitor){
            cacheLinuxMonitor.put(key,object);
        }
    }
    public static <T> T getCacheLinuxMonitor(String key){
        synchronized (cacheLinuxMonitor){
            return (T)cacheLinuxMonitor.get(key);
        }
    }

    public static void setTcpConnected(boolean connected){
        synchronized (tcpConnectedLock){
            tcpConnected = connected;
        }
    }
    public static boolean hasTcpConnected(){
        synchronized (tcpConnectedLock){
            return tcpConnected;
        }
    }
}
